package com.lightsh.jbox2d;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;

import com.lightsh.action.ApplyForce;
import com.lightsh.body.PolygonImpl;
import com.lightsh.body.RectangleImpl;
import com.lightsh.graphics.ImageUtility;
import com.lightsh.gui.GameSurfaceView;
import com.lightsh.gui.PhysicsScreen;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import com.lightsh.jbox2d.R;
import com.lightsh.things.BulletCircle;
import com.lightsh.things.Gun;

public class SurfaceViewActivity extends Activity{

	private GameSurfaceView mSurfaceView; 
	private PhysicsScreen mScreen;	
	private SensorEventListener mSensorLitener;
	
	private static final int MSG_GENERATE_THINGS = 1;
	private Handler mHandler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			switch(msg.what){
			case MSG_GENERATE_THINGS:{
				generateThings();
				break;
			}
			}
			super.handleMessage(msg);
		}
		
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);		
		mSurfaceView = new GameSurfaceView(this);
		
		int screenW = getWindowManager().getDefaultDisplay().getWidth();
		int screenH = getWindowManager().getDefaultDisplay().getHeight();
		
		mScreen = new PhysicsScreen(this, screenW, screenH, screenW , screenH);
		mScreen.createWorld(1/10f, false);
		mScreen.setBackgroundBitmap(ImageUtility.drawableToBitmap(getResources().getDrawable(R.drawable.background)));
		
//		mScreen.getWorld().setGravity(new Vec2(0, 2f));
		mScreen.enableSensor(false);
		
		// 设置负责游戏绘制和事件处理的screen
		mSurfaceView.setGameScreen(mScreen);		
		
		setContentView(mSurfaceView);
		
		mHandler.sendEmptyMessageDelayed(MSG_GENERATE_THINGS, 100);
	}
	
	// 不能在其他线程中创建world对象。应该使用一个临时队列，在update()方法中进行创建
	private void generateThings(){
		Gun gun = new Gun(mScreen, 100, 300, 1, 0, 0);		
		gun.setGenerateBulletInterval(30);
		mScreen.addBodyToScreen(gun);
		
		gun = new Gun(mScreen, mScreen.getScreenWidth() - 150, 300, 1, 0, 0);	
		gun.setTargetRadian((float)Math.PI);
		gun.setGenerateBulletInterval(30);
		mScreen.addBodyToScreen(gun);
		
		// equal gun.create();
		
		
//		mScreen.createCircle(30, 30, 30, 1f, 0.5f, 0.5f).setLinearDamping(0.1f);
//		mScreen.createCircle(100, 100, 30, 5f, 0.5f, 0.5f).setLinearDamping(0.5f);
//		Circle circle = mScreen.createCircle(150, 150, 23f, 10f, 0.5f, 0.5f);
//		circle.setLinearDamping(1.0f);
//		circle.bindSprite(new Sprite(ImageUtility.drawableToBitmap(getResources().getDrawable(R.drawable.pig)), 46, 46, 10));
		
//		mScreen.createRectangle(350, 350, 36, 36, 1f, 1f, 0f).bindBitmap(ImageUtility.drawableToBitmap(getResources().getDrawable(R.drawable.icon)));
//		
//		testThread();
//		
		
		
//		// 五角星,不能时凹形图形...
//		// 点的总数做了限制?
//		final Vec2[] fStarVecs = new Vec2[]{
//			new Vec2(0, -4),
//			//new Vec2(1, -2),
//			new Vec2(4, -2),
//			//new Vec2(2, 0),
//			new Vec2(3, 3),
//			//new Vec2(0, 1),
//			new Vec2(-3, 3),
//			//new Vec2(-2, 0),
//			new Vec2(-4, -2),
//			//new Vec2(-1, -2)
//		};
//		testThread();		
//		float scale = 10f;
//		PolygonImpl fiveStar = new PolygonImpl(mScreen, 200, 200, 10, 10, 0f);		
//		for(Vec2 vec : fStarVecs){
//			fiveStar.add(vec.mul(scale), vec == fStarVecs[fStarVecs.length - 1]);
//		}
//		mScreen.addBodyToScreen(fiveStar);
//		testThread();
//		
//		PolygonImpl triangle = new PolygonImpl(mScreen, 50f, 50f, 1f, 1f, 0.1f);
//		triangle.add(new Vec2(0, -20), false);
//		triangle.add(new Vec2(20, 20), false);
//		triangle.add(new Vec2(-20, 20), true);
//		mScreen.addBodyToScreen(triangle);
//		testThread();
		
		

		float friction = 1f;
		RectangleImpl left = new RectangleImpl(mScreen, 0, mScreen.getWorldHeight() >> 1, 3, mScreen.getWorldHeight() >> 1, 0, friction, 0.1f);		
		RectangleImpl right = new RectangleImpl(mScreen, mScreen.getWorldWidth(), mScreen.getWorldHeight() >> 1, 3, mScreen.getWorldHeight() >> 1, 0, friction, 0.1f);
		RectangleImpl top = new RectangleImpl(mScreen, mScreen.getWorldWidth() >> 1, 0, mScreen.getWorldWidth() >> 1, 3, 0, friction, 0.1f);
//		RectangleImpl bottmp = new RectangleImpl(mScreen, mScreen.getWorldWidth() >> 1, mScreen.getWorldHeight(), mScreen.getWorldWidth() >> 1, 3, 0, friction, 0.1f);
		
//		testThread();
		left.setColor(Color.RED);
		right.setColor(Color.RED);
		top.setColor(Color.RED);
//		bottmp.setColor(Color.RED);
		
		mScreen.addBodyToScreen(left);
		mScreen.addBodyToScreen(right);
		mScreen.addBodyToScreen(top);
//		mScreen.addBodyToScreen(bottmp);
		
//		testDynamicCreateThings();
		
	}
	
	public static void testThread(){
		Thread.yield();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		super.onPause();
		checkSensorState(false);
	}

	@Override
	protected void onResume() {
		super.onResume();
		checkSensorState(true);
	}


	private void checkSensorState(boolean isOpen){
		try{
			SensorManager sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
			if(isOpen && mScreen != null && mScreen.isSensorEnable()){
				if(mSensorLitener == null){
					mSensorLitener = new SensorEventListener() {
						
						@Override
						public void onSensorChanged(SensorEvent event) {
							if(mScreen != null){
								mScreen.onSensorChange(event);
							}							
						}
						
						@Override
						public void onAccuracyChanged(Sensor sensor, int accuracy) {
							
						}
					};
				}
				sm.registerListener(mSensorLitener, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
			}else{
				if(mSensorLitener != null){
					sm.unregisterListener(mSensorLitener);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		return mScreen.onKeyDown(keyCode, event) ? true : super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		return mScreen.onKeyUp(keyCode, event) ? true : super.onKeyUp(keyCode, event);
	}
	
	private void testDynamicCreateThings(){
		new Thread(new Runnable() {			
			@Override
			public void run() {
				while(true){
					
					Vec2 vec2 = new Vec2(20, 200);
					BulletCircle circle = new BulletCircle(mScreen, vec2.x + 10, vec2.y, 6, 1, 1, 0);
					circle.setColor(Color.BLACK);
					circle.addAction(new ApplyForce(circle, new Vec2(50000, 0)));
					mScreen.addBodyToScreen(circle);
					// 以上两句相似的操作为下面两句，但是下面两句会随机出现异常，因为当前线程与world的step()线程会冲突造成奇怪的现象
					// circle.create();
					// circle.applyForce(new Vec2(50000, 0));
					
					try {
						Thread.sleep(500);
					} catch (InterruptedException ignore) {
					}
				}
				
			}
		}).start();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(0, 0, 0, "");
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		MenuItem item = menu.getItem(0);
		if(mScreen.isPause()){
			item.setTitle(getString(R.string.begin));
		}else{
			item.setTitle(getString(R.string.pause));
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch(item.getItemId()){
		case 0:{
			if(mScreen.isPause()){
				mScreen.resume();
			}else{
				mScreen.pause();
			}
			break;
		}
		}
		return true;
	}
	
	
	
}
